package com.css.bjdt_core.report.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.css.bjdt_core.executive.report.ReportCache;
import com.css.bjdt_core.report.entity.RptAreaTemporary;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.css.bjdt_core.executive.entity.Exp;
import com.css.bjdt_core.report.entity.RptTemplateCalc;
import com.css.bjdt_core.report.entity.RptTemplateCalc.CalcType;
import com.css.bjdt_core.util.CommonUtil;
import com.css.bjdt_core.util.PageQuerys;

@Service
public class ReportCalcService {
	@Autowired
	private Dao dao;

	private ReportCache cache = ReportCache.getInstance();

	public RptTemplateCalc insert(RptTemplateCalc record) {
		if (record == null) {
			return null;
		}
		if (StringUtils.isBlank(record.getCalcId())) {
			record.setCalcId(CommonUtil.getUUID());
		}
		return dao.insert(record);
	}

	//批量保存该报表的计算公式
	public void insertList(List<RptTemplateCalc> list) {
		for (RptTemplateCalc rptTemplateCalc : list) {
			insert(rptTemplateCalc);
		}
	}

	public boolean delete(String recordId) {
		if (StringUtils.isBlank(recordId)) {
			return false;
		}
		dao.delete(RptTemplateCalc.class, recordId);
		return true;
	}

	public void update(RptTemplateCalc record) {
		dao.updateIgnoreNull(record);
	}

	public RptTemplateCalc getReportCalcById(String recordId) {
		if (StringUtils.isBlank(recordId)) {
			return null;
		}
		return dao.fetch(RptTemplateCalc.class, recordId);
	}

	//根据报表ID和区域ID，取得当前区域的所有计算公式
	public List<RptTemplateCalc> getReportCalcByType(String templateId, CalcType type, String temporaryId) {
		return dao.query(RptTemplateCalc.class, Cnd.where("TEMPLATE_ID", "=", templateId)
				.and("CALC_TYPE", "=", type.getKey()).and("AREA_TEMPORARY_ID", "=", temporaryId).desc("ORDER_ID"));
	}

	//根据报表ID取得该报表的所有的计算公式
	public List<RptTemplateCalc> getRawReportCalcByType(String templateId, CalcType type) {
		return dao.query(RptTemplateCalc.class,
				Cnd.where("TEMPLATE_ID", "=", templateId).and("CALC_TYPE", "=", type.getKey()).desc("ORDER_ID"));
	}

	//根据报表ID取得该报表的所有的计算公式
	public List<RptTemplateCalc> getReportCalcByType(String templateId, CalcType type) {
		List<RptTemplateCalc> res = (List<RptTemplateCalc>) cache.get(ReportCache.CALC_CACHE, templateId + type.getKey());
		if(res == null) {
			res = dao.query(RptTemplateCalc.class,
					Cnd.where("TEMPLATE_ID", "=", templateId).and("CALC_TYPE", "=", type.getKey()).desc("ORDER_ID"));
			cache.put(ReportCache.CALC_CACHE, templateId+type.getKey(), res);
		}
		return res;
	}

	public Map<String, List<Exp>> buildReportCalcMapByTemplateId(String templateId) {
		Map<String, List<Exp>> reportCalcMap = new HashMap<String, List<Exp>>();
		List<RptTemplateCalc> rowCalcs = getRawReportCalcByType(templateId, CalcType.row);
		reportCalcMap.put(CalcType.row.getKey(), buildExpObj(rowCalcs));
		List<RptTemplateCalc> colCalcs = getRawReportCalcByType(templateId, CalcType.col);
		reportCalcMap.put(CalcType.col.getKey(), buildExpObj(colCalcs));
		List<RptTemplateCalc> cellCalcs = getRawReportCalcByType(templateId, CalcType.cell);
		reportCalcMap.put(CalcType.cell.getKey(), buildExpObj(cellCalcs));
		return reportCalcMap;
	}

	private List<Exp> buildExpObj(List<RptTemplateCalc> calcs) {
		List<Exp> list = new ArrayList<Exp>();
		for (RptTemplateCalc calc : calcs) {
			list.add(new Exp(calc));
		}
		return list;
	}

	public Map queryPage(Condition cnd, int pageNum, int pageSize) {
		return PageQuerys.ligerGridQuery(dao, RptTemplateCalc.class, cnd, pageNum, pageSize);
	}

	//通过报表ID删除所有计算条件
	public void deleteByTemplateId(String templateId) {
		dao.clear(RptTemplateCalc.class, Cnd.where("TEMPLATE_ID", "=", templateId));
	}

	//根据报表ID获得所有行列计算式
	public List<RptTemplateCalc> queryAllRptTemplateCalcByTemplateId(String templateId) {
		SqlExpressionGroup g1 = Cnd.exps("CALC_TYPE", "=", CalcType.row.getKey());
		SqlExpressionGroup g2 = Cnd.exps("CALC_TYPE", "=", CalcType.col.getKey());
		List<RptTemplateCalc> rptTemplateCalcList = dao.query(RptTemplateCalc.class,
				Cnd.where("TEMPLATE_ID", "=", templateId).and(g1.or(g2)));
		return rptTemplateCalcList;
	}

}
